package com.zhstudyjava.ai.repository;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.document.Document;
import org.springframework.ai.reader.pdf.PagePdfDocumentReader;
import org.springframework.ai.reader.pdf.config.PdfDocumentReaderConfig;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Properties;

@Slf4j
@Component
@RequiredArgsConstructor
public class LocalPdfFileRepository implements FileRepository {


    private final VectorStore redisVectorStore;

    // 会话id 与 文件名的对应关系，方便查询会话历史时重新加载文件
    private final Properties chatFiles = new Properties();

    @Override
    public boolean save(String chatId, Resource resource) {
        String filename = resource.getFilename();
        File target = new File(Objects.requireNonNull(filename));
        if (!target.exists()) {
            try {
                Files.copy(resource.getInputStream(), target.toPath());
            } catch (IOException e) {
                log.error("Failed to save PDF resource.", e);
                return false;
            }
        }

        // 将 PDF 内容读取并写入 RedisVectorStore
        try {
            PagePdfDocumentReader reader = new PagePdfDocumentReader(
                    new FileSystemResource(target),
                    PdfDocumentReaderConfig.builder()
                            .withPagesPerDocument(1)
                            .build()
            );

            List<Document> documents = reader.read();
            for (Document doc : documents) {
                doc.getMetadata().put("file_name", filename); // 添加元数据
            }
            redisVectorStore.add(documents); // 将文档写入 Redis 向量库
        } catch (Exception e) {
            log.error("Failed to add document to RedisVectorStore", e);
            return false;
        }

        chatFiles.put(chatId, filename); // 保存映射关系
        return true;
    }

    @Override
    public Resource getFile(String chatId) {
        String filename = chatFiles.getProperty(chatId);
        if (filename == null) {
            return null;
        }
        File file = new File(filename);
        return file.exists() ? new FileSystemResource(file) : null;
    }

    @PostConstruct
    private void init() {
        FileSystemResource pdfResource = new FileSystemResource("chat-pdf.properties");
        if (pdfResource.exists()) {
            try {
                chatFiles.load(new BufferedReader(new InputStreamReader(pdfResource.getInputStream(), StandardCharsets.UTF_8)));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        // 不再从 chat-pdf.json 加载数据到 RedisVectorStore
        log.info("RedisVectorStore 已自动初始化，无需手动加载.");
    }

    @PreDestroy
    private void persistent() {
        try (OutputStreamWriter writer = new OutputStreamWriter(
                new FileOutputStream("chat-pdf.properties"), StandardCharsets.UTF_8)) {
            chatFiles.store(writer, LocalDateTime.now().toString());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // RedisVectorStore 数据已持久化在 Redis 中，无需额外保存到本地文件
        log.info("Chat file mappings persisted, RedisVectorStore data is already stored in Redis.");
    }
}